package bookworm;

import java.util.LinkedList;

import retrievedatafromrevishapi.AccessBooksData;

/**
 * a class responsible for calculating any rating in our system: from book reviewer ratings
 * to book ratings. Here we present all the calculus of ratings  
 *
 */
public class CalculatesRatingsBookworm 
{
	/**
	 * given the reviewer name, it calculates a grade from 0 to 5 for the reviewer. The
	 * result is based in the number of reviews he/she wrote and the number of books in 
	 * his/her history.
	 * @param reviewerName the reviewer's name.
	 * @return
	 */
	public static int calculateReviewerRating(String reviewerName)
	{
		LinkedList<String> searchArguments = new LinkedList<String>();
		searchArguments.add("user");
		LinkedList<String> argumentsValues = new LinkedList<String>();
		argumentsValues.add(reviewerName);
		AccessBooksData getsReviewsMadeFromReviewer = AccessBooksData.getAccessBooksData();
		int numberOfReviewsWritten = getsReviewsMadeFromReviewer.getNumberOfBookReviewsFromRevishAPI(searchArguments, argumentsValues);
		
		int averageNumberOfBookReviewsWritten = 8;//average from all the reviewers of our system
		
		int reviewerRatingNumberOfReviewsWritten = ((3 * numberOfReviewsWritten) / averageNumberOfBookReviewsWritten);
		if(reviewerRatingNumberOfReviewsWritten > 5)
		{
			reviewerRatingNumberOfReviewsWritten = 5;
		}
		
		int numberOfBooksInHistory = getsReviewsMadeFromReviewer.getNumberOfBooksInHistoryFromRevishAPI(reviewerName);
		
		int averageReviewsInHistory = 16;
		int reviewerRatingReadingHistory = ((3 * numberOfBooksInHistory) / averageReviewsInHistory); 
		if(reviewerRatingReadingHistory > 5)
		{
			reviewerRatingReadingHistory = 5;
		}
		
		int reviewerRating = (reviewerRatingNumberOfReviewsWritten + reviewerRatingReadingHistory) / 2;
		
		return reviewerRating;
	}
	
	
	/**
	 * based on the rating of the reviewers and on the rating of the reviews we'll calculate the
	 * average rating of a book. This rating will go from 0 to 5 stars 
	 * @param book
	 * @return
	 */
	public static int calculateAverageRatingOfBook(Book book)
	{
		int sumOfAllRatingsOfReviews = 0;
		int sumOfAllRatingsOfReviewers = 0;
		LinkedList<Review> reviewsFromABook = book.getReviewsFromABook();
		for(int i = 0; i < reviewsFromABook.size(); i++)
		{
			Review reviewFromBook = reviewsFromABook.get(i);
			int ratingOfReview = reviewFromBook.getRating();
			int ratingOfReviewer = reviewFromBook.getReviewerRating();
			sumOfAllRatingsOfReviews = sumOfAllRatingsOfReviews + ratingOfReview;
			sumOfAllRatingsOfReviewers = sumOfAllRatingsOfReviewers + ratingOfReviewer;
		}
		
		int numberOfReviews = reviewsFromABook.size();
		
		int averageRatingBasedOnReviews = (sumOfAllRatingsOfReviews / numberOfReviews);
		int averageRatingBasedOnReviewers = (sumOfAllRatingsOfReviewers / numberOfReviews);
		int averageRatingFromABook =
				(averageRatingBasedOnReviews + averageRatingBasedOnReviewers) / 2;
		
		return averageRatingFromABook;
	}
	
	/**
	 * with the books from a specific author and from a specific tag, we'll calculate
	 * the average rating of the author (for the tag) based on the ratings of the books
	 * (from the tag). This rating will go from 0 to 5 stars
	 * @param booksFromAuthorAndSpecificTag
	 * @return
	 */
	public static int calculateAverageRatingOfAuthorBasedOnSpecificTag(LinkedList<Book> 
																booksFromAuthorAndSpecificTag)
	{
		int sumOfRatingsOfBooksFromAuthorAndSpecificTag = 0;
		for(int i = 0; i < booksFromAuthorAndSpecificTag.size(); i++)
		{
			Book oneBook = booksFromAuthorAndSpecificTag.get(i);
			int ratingOfOneBook = oneBook.getAverageRatingFromABook();
			sumOfRatingsOfBooksFromAuthorAndSpecificTag =
					sumOfRatingsOfBooksFromAuthorAndSpecificTag + ratingOfOneBook;
		}
		
		int numberOfBooksFromAuthorAndSpecifiedTag = booksFromAuthorAndSpecificTag.size();
		
		if(numberOfBooksFromAuthorAndSpecifiedTag == 0)
		{
			//no books from author and specified tag were found, so the rating will be -1
			return -1;
		}
		else
		{
			int averageRatingOfAuthorBasedOnSpecificTag = 
					sumOfRatingsOfBooksFromAuthorAndSpecificTag/numberOfBooksFromAuthorAndSpecifiedTag;
			return averageRatingOfAuthorBasedOnSpecificTag;
		}
	}

}
